package com.itheima.service.impl;

import com.itheima.mapper.OrdersettingMapper;
import com.itheima.pojo.OrderSetting;
import com.itheima.service.OrdersettingService;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.CellType;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.multipart.MultipartFile;

import java.io.IOException;
import java.io.InputStream;
import java.time.LocalDate;
import java.time.YearMonth;
import java.time.ZoneId;
import java.util.*;
import java.util.stream.Collectors;

@Slf4j
@Service
public class OrdersettingServiceImpl implements OrdersettingService {
    @Autowired
    private OrdersettingMapper ordersettingMapper;

    // Excel模板配置
    private static final int DATE_COLUMN_INDEX = 0;
    private static final int NUMBER_COLUMN_INDEX = 1;

    /**
     * 根据时间修改可预约人数
     *
     * @param orderSetting
     */
    public void updateNumberByOrderDate(OrderSetting orderSetting) {
        ordersettingMapper.updateNumberByOrderDate(orderSetting);
    }

    /**
     * 根据年月查询对应的预约设置信息
     *
     * @param month
     * @return
     */
    public List<OrderSetting> getOrderSettingByMonth(String month) {
        //把字符串month用“-”分隔开，形成一个数组
        String[] split = month.split("-");
        //如果月份是1，2，3，4，5，，6，7，8，9，就在前面加0
        if (split[1].length() == 1) {
            split[1] = "0" + split[1];
        }
        month=split[0] + "-" + split[1];
        log.info("当前month：{}",month);
        //根据字符串，计算出当前月份的第一天和最后一天
        LocalDate firstDayOfMonth = YearMonth.parse(month).atDay(1);
        LocalDate lastDayOfMonth = firstDayOfMonth.withDayOfMonth(firstDayOfMonth.lengthOfMonth());
        //根据月份查询预约设置信息
        return ordersettingMapper.getOrderSettingByMonth(firstDayOfMonth, lastDayOfMonth);
    }

    /**
     * 批量导入预约设置信息
     *
     * @param inputStream
     */
    @Transactional
    public void processExcel(InputStream inputStream) throws IOException {
        List<OrderSetting> orderSettings = new ArrayList<>();

        try (XSSFWorkbook workbook = new XSSFWorkbook(inputStream)) {
            //获取第一个工作表
            XSSFSheet sheet = workbook.getSheetAt(0);

            //遍历工作表中的每一行（跳过标题行）
            for (Row row : sheet) {
                if (row.getRowNum() == 0) {
                    continue;
                }
                //解析日期单元格
                LocalDate orderDate = parseDateCell(row.getCell(DATE_COLUMN_INDEX));

                //解析日期人数
                int number = parseNumberCell(row.getCell(NUMBER_COLUMN_INDEX));

                orderSettings.add(new OrderSetting(
                        Date.from(orderDate.atStartOfDay(ZoneId.systemDefault()).toInstant()),
                        number));
            }
        }
        // 数据基础校验（检查空数据、日期格式等）
        validateBasicData(orderSettings);

        // 获取所有日期并删除旧数据
        List<Date> datesToDelete = orderSettings.stream()
                .map(OrderSetting::getOrderDate)
                .collect(Collectors.toList());
        ordersettingMapper.deleteByDates(datesToDelete);

        // 批量插入新数据
        ordersettingMapper.batchInsert(orderSettings);
    }


    private void validateBasicData(List<OrderSetting> settings) {
        // 空数据校验
        if (settings.isEmpty()) {
            throw new RuntimeException("Excel文件中没有有效数据");
        }

        // 重复日期校验
        Set<Date> uniqueDates = new HashSet<>();
        for (OrderSetting setting : settings) {
            if (!uniqueDates.add(setting.getOrderDate())) {
                throw new RuntimeException("文件中存在重复日期：" + setting.getOrderDate());
            }
        }

        // 预约人数合法性校验
        for (OrderSetting setting : settings) {
            if (setting.getNumber() <= 0) {
                throw new RuntimeException(String.format(
                        "%tF 预约人数必须大于0", setting.getOrderDate()
                ));
            }
        }
    }

    /**
     * 解析日期单元格
     * @param cell
     * @return
     */
    private LocalDate parseDateCell(Cell cell) {
        try {
            if (cell.getCellTypeEnum() == CellType.NUMERIC){
                return cell.getDateCellValue().toInstant()
                        .atZone(ZoneId.systemDefault()).toLocalDate();
            }
            return LocalDate.parse(cell.getStringCellValue());
        }catch (Exception e){
            throw new RuntimeException("第"+(cell.getRowIndex()+1)+"行日期格式不正确");
        }
    }

    /**
     * 解析日期人数
     * @param cell
     * @return
     */
    private int parseNumberCell(Cell cell) {
        if (cell.getCellTypeEnum() == CellType.NUMERIC) {
            return (int) cell.getNumericCellValue();
        }
        throw new RuntimeException("第" + (cell.getRowIndex()+1) + "行人数格式错误");
    }
}
